using AutoMapper;
using MediatR;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.MaterialFile.Department;
using System.Transactions;
using Microsoft.Extensions.Logging;
using RBAC.Domain.Department;

namespace RBAC.Write.Api.Application.Handler.ERP.MaterialFile.Department
{
    /// <summary>
    /// 创建部门处理类
    /// </summary>
    public class CreateDepartmentHandler : IRequestHandler<CreateDepartmentCommand, APIResult<int>>
    {
        private readonly IBaseRepository<DepartmentManagement> departmentRepository;
        private readonly ILogger<CreateDepartmentHandler> logger;
        private readonly IMapper mapper;

        public CreateDepartmentHandler(
            IBaseRepository<DepartmentManagement> departmentRepository,
            ILogger<CreateDepartmentHandler> logger,
            IMapper mapper)
        {
            this.departmentRepository = departmentRepository;
            this.logger = logger;
            this.mapper = mapper;
        }

        /// <summary>
        /// 创建部门
        /// </summary>
        /// <param name="request">创建部门请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>创建结果</returns>
        public Task<APIResult<int>> Handle(CreateDepartmentCommand request, CancellationToken cancellationToken)
        {
            APIResult<int> res = new APIResult<int>();

            try
            {
                logger.LogInformation("开始创建部门: {DepartmentName}", request.DepartmentName);

                // 1. 数据验证
                if (string.IsNullOrWhiteSpace(request.DepartmentName))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "部门名称不能为空";
                    logger.LogWarning("部门名称验证失败");
                    return Task.FromResult(res);
                }

                if (request.DepartmentName.Length > 50)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "部门名称长度不能超过50个字符";
                    logger.LogWarning("部门名称长度验证失败: {Length}", request.DepartmentName.Length);
                    return Task.FromResult(res);
                }

                if (request.Status != 0 && request.Status != 1)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "部门状态只能是0(禁用)或1(启用)";
                    logger.LogWarning("部门状态验证失败: {Status}", request.Status);
                    return Task.FromResult(res);
                }

                // 2. 检查部门名称是否已存在
                var existingDepartment = departmentRepository.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM Department WHERE DepartmentName = @DepartmentName AND IsDeleted = false", 
                    new { DepartmentName = request.DepartmentName });
                
                if (existingDepartment > 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "部门名称已存在";
                    logger.LogWarning("部门名称已存在: {DepartmentName}", request.DepartmentName);
                    return Task.FromResult(res);
                }

                // 3. 验证上级部门是否存在（如果有上级部门）
                if (request.ParentId.HasValue && request.ParentId.Value > 0)
                {
                    var parentDepartment = departmentRepository.QueryFirstOrDefault<int>(
                        "SELECT COUNT(1) FROM Department WHERE Id = @Id AND IsDeleted = false", 
                        new { Id = request.ParentId.Value });
                    
                    if (parentDepartment == 0)
                    {
                        res.Code = APIEnums.Error;
                        res.Msg = "指定的上级部门不存在";
                        logger.LogWarning("上级部门验证失败: {ParentId}", request.ParentId.Value);
                        return Task.FromResult(res);
                    }
                }

                // 4. 创建部门实体
                var department = mapper.Map<DepartmentManagement>(request);
                department.CreateTime = DateTime.Now;
                department.IsDeleted = false;

                logger.LogInformation("部门映射完成: DepartmentName={DepartmentName}, ParentId={ParentId}", 
                    department.DepartmentName, department.ParentId);

                using (TransactionScope tran = new TransactionScope())
                {
                    try
                    {
                        // 5. 保存部门信息 - 使用自定义SQL绕过仓储的表名映射问题
                        // 添加CreateUser字段，使用默认用户ID 1（管理员）
                        // 根据错误信息，确保所有必填字段都有值
                        // 移除了不存在的CreateUserName字段，只保留实际存在的字段
                        var sql = @"INSERT INTO Department (DepartmentName, ParentId, Sort, Status, CreateTime, IsDeleted, CreateUser) 
                                   VALUES (@DepartmentName, @ParentId, @Sort, @Status, @CreateTime, @IsDeleted, @CreateUser);
                                   SELECT LAST_INSERT_ID();";
                        
                        var parameters = new 
                        {
                            department.DepartmentName,
                            department.ParentId,
                            department.Sort,
                            department.Status,
                            department.CreateTime,
                            department.IsDeleted,
                            CreateUser = 1 // 默认管理员用户ID
                        };
                        
                        var departmentId = departmentRepository.QueryFirstOrDefault<int>(sql, parameters);
                        
                        if (departmentId <= 0)
                        {
                            throw new InvalidOperationException("部门创建失败，返回的ID无效");
                        }

                        tran.Complete();

                        res.Code = APIEnums.Success;
                        res.Data = departmentId;
                        res.Msg = "部门创建成功";

                        logger.LogInformation("部门 {DepartmentName} 创建完成，ID: {DepartmentId}", 
                            request.DepartmentName, departmentId);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "创建部门过程中发生错误: {Message}", ex.Message);
                        res.Code = APIEnums.Error;
                        res.Msg = "创建部门失败";
                        res.Data = 0;
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "创建部门失败: {Message}", ex.Message);
                res.Code = APIEnums.Error;
                res.Msg = "创建部门失败";
                res.Data = 0;
            }

            return Task.FromResult(res);
        }
    }
}